<?php
/**
 * Created by PhpStorm.
 * User: Winter
 * Date: 2020/4/3 0003
 * Time: 16:23
 */

/**
 * 01分级排序
 * @param $data
 * @param int $pid
 * @param string $field
 * @param string $pk
 * @param string $html
 * @param int $level
 * @param bool $clear
 * @return array
 */
function sort_list_tier($data, $pid = 0, $field = 'pid', $pk = 'id', $html = '|-----', $level = 1, $clear = true)
{
    static $list = [];
    if ($clear) $list = [];
    foreach ($data as $k => $res) {
        if ($res[$field] == $pid) {
            $res['html'] = str_repeat($html, $level);
            $list[] = $res;
            unset($data[$k]);
            sort_list_tier($data, $res[$pk], $field, $pk, $html, $level + 1, false);
        }
    }
    return $list;
}

/**
 * 02写入配置文件方法
 * @param  [type] $arr      [要写入的数据]
 * @param  [type] $filename [文件路径]
 * @return [type]           [description]
 */
function writeArr($arr, $filename) {
    return file_put_contents($filename, "<?php\r\nreturn " . var_export($arr, true) . ";");
}

/**
 * 03删除目录下所有文件
 * @param $path 目录或者文件路径
 * @param string $ext
 * @return bool
 */
function clearfile($path,$ext = '*.log')
{
    $files = (array) glob($path.DS.'*');
    foreach ($files as $path) {
        if (is_dir($path)) {
            $matches = glob($path . '/'.$ext);
            if (is_array($matches)) {
                array_map('unlink', $matches);
            }
            rmdir($path);
        } else {
            unlink($path);
        }
    }
    return true;
}

/**
 * 04返回随机数
 * @param int $length
 * @param int $numeric
 * @return string
 */
function random($length = 6, $numeric = 0)
{
    PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
    if ($numeric) {
        $hash = sprintf('%0' . $length . 'd', mt_rand(0, pow(10, $length) - 1));
    } else {
        $hash = '';
        $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghjkmnpqrstuvwxyz';
        $max = strlen($chars) - 1;
        for ($i = 0; $i < $length; $i++) {
            $hash .= $chars[mt_rand(0, $max)];
        }
    }
    return $hash;

}

/**
 * 05生成指定长度的随机字符串并返回。
 * @param $length
 * @param bool|false $numeric
 * @return string
 */
function randomOne($length, $numeric = false) {
    $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
    $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
    if ($numeric) {
        $hash = '';
    } else {
        $hash = chr(rand(1, 26) + rand(0, 1) * 32 + 64);
        $length--;
    }
    $max = strlen($seed) - 1;
    for ($i = 0; $i < $length; $i++) {
        $hash .= $seed{mt_rand(0, $max)};
    }
    return $hash;
}

/**
 * 06字符串中间加*
 * @param string $string 需要替换的字符串
 * @param int $start 开始的保留几位
 * @param int $end 最后保留几位
 * @return string
 */
function strReplace($string, $start, $end)
{
    $strlen = mb_strlen($string, 'UTF-8');//获取字符串长度
    $firstStr = mb_substr($string, 0, $start, 'UTF-8');//获取第一位
    $lastStr = mb_substr($string, -1, $end, 'UTF-8');//获取最后一位
    return $strlen == 2 ? $firstStr . str_repeat('*', mb_strlen($string, 'utf-8') - 1) : $firstStr . str_repeat("*", $strlen - 2) . $lastStr;

}

/**
 * 07敏感词过滤
 * @param string
 * @return string
 */
function sensitive_words_filter($str)
{
    if (!$str) return '';
    $file = app()->getAppPath() . 'public/static/plug/censorwords/CensorWords';
    $words = file($file);
    foreach ($words as $word) {
        $word = str_replace(array("\r\n", "\r", "\n", "/", "<", ">", "=", " "), '', $word);
        if (!$word) continue;

        $ret = preg_match("/$word/", $str, $match);
        if ($ret) {
            return $match[0];
        }
    }
    return '';
}

/**
 * 08将参数转换为HTTP绝对路径并返回
 * @param $src
 * @param string $ext_path
 * @return mixed|string
 */
function to_media($src,$ext_path = '/uploads/'){
    if (empty($src)) {
        return '';
    }
    $src = strtolower($src);
    //如果已经是网络图片，返回原地址
    if (str_exists($src, 'http://') || str_exists($src, 'https://')) {
        return $src;
    }
    //默认本地uploads下的文件，转为网络地址
    return str_replace('\\','/',"{$ext_path}{$src}");
}

/**
 * 09文件字节转大小 K/M
 * @param $size
 * @return string
 */
function format_file_size($size){
    $units = array(' B', ' KB', ' MB', ' GB', ' TB');
    for ($i = 0; $size >= 1024 && $i < 4; $i++){
        $size /= 1024;
    }
    return round($size, 2).$units[$i];
}

/**
 * 10json格式返回数据
 * @param array $data
 * @param string $message
 * @param int $code
 */
function to_json($code = 0,$message = '访问成功',$data =[]){
    // utf-8编码
    @header('Content-Type: application/json; charset=utf-8');
    exit(json_encode(array(
        'data' => $data,
        'message' => $message,
        'code' => $code
    )));
}

/**
 * 11请求
 * @param $url
 * @param array $params
 * @return mixed
 */
function simple_curl($url, $params = array()) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
    $ret = curl_exec($curl);
    curl_close($curl);
    return $ret;
}

/**
 * 12友好时间显示
 * @param $time
 * @return bool|false|string
 */
function date_friend_tips($time){
    if (!$time)
        return false;
    $d = TIMESTAMP - intval($time);
    $ld = $time - mktime(0, 0, 0, 0, 0, date('Y')); //得出年
    $md = $time - mktime(0, 0, 0, date('m'), 0, date('Y')); //得出月
    $byd = $time - mktime(0, 0, 0, date('m'), date('d') - 2, date('Y')); //前天
    $yd = $time - mktime(0, 0, 0, date('m'), date('d') - 1, date('Y')); //昨天
    $dd = $time - mktime(0, 0, 0, date('m'), date('d'), date('Y')); //今天
    $td = $time - mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')); //明天
    $atd = $time - mktime(0, 0, 0, date('m'), date('d') + 2, date('Y')); //后天
    if ($d == 0) {
        $fdate = '刚刚';
    } else {
        switch ($d) {
            case $d < $atd:
                $fdate = date('Y年m月d日', $time);
                break;
            case $d < $td:
                $fdate = '后天' . date('H:i', $time);
                break;
            case $d < 0:
                $fdate = '明天' . date('H:i', $time);
                break;
            case $d < 60:
                $fdate = $d . '秒前';
                break;
            case $d < 3600:
                $fdate = floor($d / 60) . '分钟前';
                break;
            case $d < $dd:
                $fdate = floor($d / 3600) . '小时前';
                break;
            case $d < $yd:
                $fdate = '昨天' . date('H:i', $time);
                break;
            case $d < $byd:
                $fdate = '前天' . date('H:i', $time);
                break;
            case $d < $md:
                $fdate = date('m月d日 H:i', $time);
                break;
            case $d < $ld:
                $fdate = date('m月d日', $time);
                break;
            default:
                $fdate = date('Y年m月d日', $time);
                break;
        }
    }
    return $fdate;
}

/**
 * 13base64转图片
 * @param $base64
 * @param string $ext
 * @param int $uid
 * @param int $admin_id
 * @return bool|string
 */
function base64_upload($base64,$ext = 'jpg',$uid = 0,$admin_id = 0) {
    if(empty($base64)){
        return false;
    }
    $base64_image = str_replace(' ', '+', $base64);//post的数据里面，加号会被替换为空格，需要重新替换回来，如果不是post的数据，则注释掉这一行
    if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image, $result)){
        $base64 = str_replace($result[1], '', $base64_image);
        $ext = $result[2];
    }
    if(!is_base64($base64)){
        return false;
    }
    $image_name = uniqid().'.'.$ext;
    $save_name = date('Ymd')."/{$image_name}";
    $image_file = ROOT_PATH . "public/uploads/{$save_name}";
    if(!is_dir(dirname($image_file))){
        make_dirs(dirname($image_file));
    }
    //服务器文件存储路径
    if (file_put_contents($image_file, base64_decode($base64))){
        $data = [
            'admin_id' => $admin_id,
            'uid' =>$uid,
            'extension' => $result[2],
            'original_name' => "base64",
            'save_name' => $save_name,
            'filename' => $image_name,
            'md5' => "",
            'sha1' => "",
            'size' => filesize($image_file),
            'create_time' => TIMESTAMP
        ];
        ;
        //数据库存入失败记录日志
        if(!\app\admin\model\Uploads::addInfo($data)){
            \think\Log::error(__FILE__.':'.__LINE__.' 错误：'.$data['save_name'].'数据库记录失败');
        }
        return $save_name;
    }
    return false;
}

/**
 * 14 获取无限极分类标题形式
 * @param $list
 * @param int $parent_id
 * @param int $level
 * @param string $html
 * @return array
 * $list 数据列可以不用以分类ID为key
 */
function category_to_tree(&$list,$parent_id=0,$level =0,$html='&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'){
    static $tree = array();
    foreach($list as $k=> $v){
        if($v['parent_id'] == $parent_id){
            if($level > 0){
                $v['title'] = str_repeat($html,$level).$v['title'];
            }
            $tree[] = $v;
            category_to_tree($list,$v['id'],$level+1);
        }
    }
    return $tree;
}

/**
 * 15根据两个经纬度算距离
 * @param $lat1
 * @param $lng1
 * @param $lat2
 * @param $lng2
 * @return float
 */
function location_distance($lat1, $lng1, $lat2, $lng2){
    $earthRadius = 6378137;//单位:m
    $lat1 = ($lat1 * M_PI)/180;
    $lng1 = ($lng1 * M_PI)/180;
    $lat2 = ($lat2 * M_PI)/180;
    $lng2 = ($lng2 * M_PI)/180;
    $calcLongitude = $lng2 - $lng1;
    $calcLatitude = $lat2 - $lat1;
    $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
    $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
    $calculatedDistance = $earthRadius * $stepTwo;
    return round($calculatedDistance);
}

/**
 * 16根据传入的经纬度，和距离范围，返回所有在距离范围内的经纬度的取值范围
 * @param $lng
 * @param $lat
 * @param float $distance 单位：km
 * @return array
 */
function location_range($lng, $lat,$distance = 0.5){
    $earthRadius = 6378.137;//单位km
    $d_lng =  2 * asin(sin($distance / (2 * $earthRadius)) / cos(deg2rad($lat)));
    $d_lng = rad2deg($d_lng);
    $d_lat = $distance/$earthRadius;
    $d_lat = rad2deg($d_lat);
    return array(
        'lat_start' => $lat - $d_lat,//纬度开始
        'lat_end' => $lat + $d_lat,//纬度结束
        'lng_start' => $lng-$d_lng,//纬度开始
        'lng_end' => $lng + $d_lng//纬度结束
    );
}

/**
 * 17php将字符串分割成数组实现中文分词
 */
function math($string,$code ='UTF-8'){
    if ($code == 'UTF-8') {
        $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
    } else {
        $pa = "/[\x01-\x7f]|[\xa1-\xff][\xa1-\xff]/";
    }
    preg_match_all($pa, $string, $t_string);
    $math=[];
    foreach($t_string[0] as $k=>$s){
        $math[]=$s;
    }
    return $math;
}

/**
 * 18检查是否手机号码
 *
 */
function check_tel($phone)
{
    if (preg_match("/^1[345678]{1}\d{9}$/", $phone)) {
        return true;
    } else {
        return false;
    }
}

/**
 * 19检查银行卡
 */
function check_card($s){
    $n = 0;
    $ns = strrev($s); // 倒序
    for ($i=0; $i <strlen($s) ; $i++) {
        if ($i % 2 ==0) {
            $n += $ns[$i]; // 偶数位，包含校验码
        }else{
            $t = $ns[$i] * 2;
            if ($t >=10) {
                $t = $t - 9;
            }
            $n += $t;
        }
    }
    return ( $n % 10 ) == 0;
}

/**
 * 20排列
 */
function arrangement($a, $m) {
    $r = array();

    $n = count($a);
    if ($m <= 0 || $m > $n) {
        return $r;
    }

    for ($i=0; $i<$n; $i++) {
        $b = $a;
        $t = array_splice($b, $i, 1);
        if ($m == 1) {
            $r[] = $t;
        } else {
            $c = arrangement($b, $m-1);
            foreach ($c as $v) {
                $r[] = array_merge($t, $v);
            }
        }
    }

    return $r;
}

/**
 * 21组合
 */
function combination($a, $m) {
    $r = array();

    $n = count($a);
    if ($m <= 0 || $m > $n) {
        return $r;
    }

    for ($i=0; $i<$n; $i++) {
        $t = array($a[$i]);
        if ($m == 1) {
            $r[] = $t;
        } else {
            $b = array_slice($a, $i+1);
            $c = combination($b, $m-1);
            foreach ($c as $v) {
                $r[] = array_merge($t, $v);
            }
        }
    }
    return $r;
}

/**
 * 22分裂红包算法
 */
function send_red($money_total,$num) {
    $rand_arr = array();
    for($i=0; $i<$num; $i++) {
        $rand = rand(1, 100);
        $rand_arr[] = $rand;
    }
    $rand_sum = array_sum($rand_arr);
    $rand_money_arr = array();
    $rand_money_arr = array_pad($rand_money_arr, $num, 0.01);  //保证每个红包至少0.01
    foreach ($rand_arr as $key => $r) {
        $rand_money = number_format($money_total*$r/$rand_sum, 2);
        if($rand_money <= 0.01 || number_format(array_sum($rand_money_arr), 2,'.','') >= number_format($money_total, 2,'.','')) {
            $rand_money_arr[$key] = 0.01;
        } else {
            $rand_money_arr[$key] = $rand_money;
        }

    }
    $max_index = $max_rand = 0;
    foreach ($rand_money_arr as $key => $rm) {
        if($rm > $max_rand) {
            $max_rand = $rm;
            $max_index = $key;
        }
    }
    unset($rand_money_arr[$max_index]);
    //这里的array_sum($rand_money_arr)一定是小于$money_total的
    $rand_money_arr[$max_index] = number_format($money_total - array_sum($rand_money_arr), 2);
    ksort($rand_money_arr);
    return $rand_money_arr;
}

/**
 * 23二维数组根据某个字段排序
 * @param array $array 要排序的数组
 * @param string $keys   要排序的键字段
 * @param string $sort  排序类型  SORT_ASC     SORT_DESC
 * @return array 排序后的数组
 */
function arraySort($array, $keys, $sort = SORT_DESC) {
    $keysValue = [];
    foreach ($array as $k => $v) {
        $keysValue[$k] = $v[$keys];
    }
    array_multisort($keysValue, $sort, $array);
    return $array;
}

/**
 * 24用户名称匿名处理
 * @param $str 	  需要处理的字符串
 * @param $subject 用来替换的字符串，默认为：星号(*)
 */
function Anonymous($str, $subject='*'){
    $len = mb_strlen($str,'utf-8');
    if($len>=6){
        $cut_start = floor($len/3);
        $cut_end = floor($len*2/3);
        $str1 = mb_substr($str,0,$cut_start,'utf-8');
        $str2 = mb_substr($str,$len-$cut_start,$cut_end,'utf-8');
    }
    else{
        $str1 = mb_substr($str,0,1,'utf-8');
        $str2 = mb_substr($str,$len-1,1,'utf-8');
    }
    $length = $len - mb_strlen($str1) - mb_strlen($str2);
    return $str1 . str_repeat($subject, $length) . $str2;
}

/**
 * 25获取中文字符拼音首字母
 * @param $str
 * @return string|null
 */
function GetFirstCharter($str){
    if(empty($str)){
        return '';
    }
    $fchar=ord($str{0});
    if($fchar>=ord('A')&&$fchar<=ord('z')) return strtoupper($str{0});
    $s1=iconv('UTF-8','gb2312',$str);
    $s2=iconv('gb2312','UTF-8',$s1);
    $s=$s2==$str?$s1:$str;
    if(empty($s{1})){
        return '';
    }
    $asc=ord($s{0})*256+ord($s{1})-65536;
    if($asc>=-20319 && $asc<=-20284) return 'A';
    if($asc>=-20283 && $asc<=-19776) return 'B';
    if($asc>=-19775 && $asc<=-19219) return 'C';
    if($asc>=-19218 && $asc<=-18711) return 'D';
    if($asc>=-18710 && $asc<=-18527) return 'E';
    if($asc>=-18526 && $asc<=-18240) return 'F';
    if($asc>=-18239 && $asc<=-17923) return 'G';
    if($asc>=-17922 && $asc<=-17418) return 'H';
    if($asc>=-17417 && $asc<=-16475) return 'J';
    if($asc>=-16474 && $asc<=-16213) return 'K';
    if($asc>=-16212 && $asc<=-15641) return 'L';
    if($asc>=-15640 && $asc<=-15166) return 'M';
    if($asc>=-15165 && $asc<=-14923) return 'N';
    if($asc>=-14922 && $asc<=-14915) return 'O';
    if($asc>=-14914 && $asc<=-14631) return 'P';
    if($asc>=-14630 && $asc<=-14150) return 'Q';
    if($asc>=-14149 && $asc<=-14091) return 'R';
    if($asc>=-14090 && $asc<=-13319) return 'S';
    if($asc>=-13318 && $asc<=-12839) return 'T';
    if($asc>=-12838 && $asc<=-12557) return 'W';
    if($asc>=-12556 && $asc<=-11848) return 'X';
    if($asc>=-11847 && $asc<=-11056) return 'Y';
    if($asc>=-11055 && $asc<=-10247) return 'Z';
    return null;
}

/**
 * 26截取字符串
 */
function Substr($str, $start = 0, $length, $charset = "utf-8", $suffix = false){
    $newStr = '';
    if (function_exists ( "mb_substr" )) {
        $newStr = mb_substr ( $str, $start, $length, $charset );
        if ($suffix && (mb_strlen($str,$charset)>$length))$newStr .= "...";
    } elseif (function_exists ( 'iconv_substr' )) {
        $newStr = iconv_substr( $str, $start, $length, $charset );
        if ($suffix && (mb_strlen($str,$charset)>$length))$newStr .= "...";
    }
    if($newStr==''){
        $re ['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re ['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re ['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re ['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all ( $re [$charset], $str, $match );
        $slice = join ( "", array_slice ( $match [0], $start, $length ) );
        if ($suffix)
            $newStr = $slice;
    }
    return $newStr;
}

/**
 * 27计算剩余时间
 */
function TimeToStr($second){
    $day = floor($second/(3600*24));
    $second = $second%(3600*24);//除去整天之后剩余的时间
    $hour = floor($second/3600);
    $second = $second%3600;//除去整小时之后剩余的时间
    $minute = floor($second/60);
    $second = $second%60;//除去整分钟之后剩余的时间
    //返回字符串
    return (($day>0)?($day.'天'):"").($hour<10?"0".$hour:$hour).':'.($minute<10?"0".$minute:$minute).':'.($second<10?"0".$second:$second);
}

/**
 * 28循环删除指定目录下的文件及文件夹
 * @param string $dirpath 文件夹路径
 */
function DelDir($dirpath){
    $dh=opendir($dirpath);
    while (($file=readdir($dh))!==false) {
        if($file!="." && $file!="..") {
            $fullpath=$dirpath."/".$file;
            if(!is_dir($fullpath)) {
                unlink($fullpath);
            } else {
                DelDir($fullpath);
                @rmdir($fullpath);
            }
        }
    }
    closedir($dh);
    $isEmpty = true;
    $dh=opendir($dirpath);
    while (($file=readdir($dh))!== false) {
        if($file!="." && $file!="..") {
            $isEmpty = false;
            break;
        }
    }
    return $isEmpty;
}

/**
 * 29获取毫秒级别的时间戳
 */
function GetMillisecond(){
    //获取毫秒的时间戳
    $time = explode ( " ", microtime () );
    $time = $time[1] . ($time[0] * 1000);
    $time2 = explode( ".", $time );
    $time = $time2[0];
    return $time;
}

/**
 * 30获取bytes 数组.
 *
 * @param $data
 *
 * @return array
 */
function getBytes(string $data)
{
    $bytes = [];
    $count = strlen($data);
    for ($i = 0; $i < $count; ++$i) {
        $byte = ord($data[$i]);
        $bytes[] = $byte;
    }

    return $bytes;
}

/**
 * 31将byte转化为string
 * @param array $bytes
 * @return string
 */
function getString(array $bytes)
{
    return implode(array_map('chr', $bytes));
}


